import re

from import_export.fields import Field
from import_export.resources import ModelResource

from .models import Hosts, Disks, Network, Accessories


class BaseResource(ModelResource):
    id = Field(attribute='id', column_name="序号")
    status = Field(attribute='get_status_display', column_name='状态')
    tp = Field(attribute='get_tp_display', column_name='品名')
    vendor = Field(attribute='vendor', column_name='品牌')
    location = Field(attribute='location', column_name='存放位置')

    class Meta:
        exclude = ('created',)

    @classmethod
    def field_from_django_field(cls, field_name, django_field, readonly):
        field = super().field_from_django_field(field_name, django_field, readonly)
        if django_field.verbose_name:
            field.column_name = django_field.verbose_name
        return field

    def before_save_instance(self, instance, using_transactions, dry_run):
        if not dry_run:
            if '使用' not in instance.get_status_display:
                instance.status = 'idle'
            for k, v in instance.TYPE_CHOICES:
                if instance.get_tp_display == v:
                    instance.tp = k


class HostsResource(BaseResource):
    disks = Field(attribute='get_disks', column_name="硬盘", readonly=True)
    mac = Field(attribute='mac', column_name="MAC", readonly=True)

    class Meta:
        model = Hosts
        exclude = ('created',)

    def dehydrate_mac(self, obj):
        macs = obj.nics.values_list('mac', flat=True)
        return macs[0] if macs else ''

    def save_m2m(self, obj, data, using_transactions, dry_run):
        if not dry_run:
            for field in self.get_import_fields():
                if field.attribute == 'get_disks' and field.column_name in data:
                    disk_str = data.get(field.column_name)
                    if disk_str is not None:
                        self.handler_disk(disk_str, obj)
                if field.attribute == 'mac' and field.column_name in data:
                    mac = data.get(field.column_name)
                    if mac and mac not in obj.nics.values_list('mac', flat=True):
                        obj.nics.add(Network(mac=mac, host=obj), bulk=False)
        super().save_m2m(obj, data, using_transactions, dry_run)

    @staticmethod
    def handler_disk(disk_str, instance):
        exist_disks = instance.disks.values_list('capacity', flat=True)
        p = re.compile(r'(\d+)([a-z])', re.I)
        ret = p.findall(disk_str)
        disks = []
        for value, unit in ret:
            value = int(value)
            if unit.upper().startswith('T'):
                value *= 1024
            if value in exist_disks:
                continue
            tp = 'hdd' if value >= 1024 else 'ssd'
            disks.append(Disks(capacity=value, tp=tp, host=instance))
        instance.disks.set(disks, bulk=False)

    def before_import_row(self, row, row_number=None, **kwargs):
        if row.get('内存') is not None:
            row['内存'] = row['内存'].split('G')[0]
        # if row.get('状态') is not None:
        #     row['状态'] = 'used' if '使用' in row['状态'] else 'idle'
        # if row.get('类型') is not None:
        #     for k, v in Hosts.TYPE_CHOICES:
        #         if row['类型'] in v:
        #             row['类型'] = k


class AccessoriesResource(BaseResource):

    class Meta:
        model = Accessories
        exclude = ('created',)
